package com.lu.manage.core.shiro;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.lu.manage.core.shiro.service.UserAuthService;
import com.lu.manage.core.utils.ToolUtil;
import com.lu.manage.modular.system.model.User;
import com.lu.manage.modular.system.service.UserService;
import cn.hutool.core.convert.Convert;
import org.apache.shiro.authc.*;
import org.apache.shiro.authc.credential.CredentialsMatcher;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.crypto.hash.Md5Hash;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;
import org.springframework.beans.factory.annotation.Autowired;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 * @program LuBoot
 * @description:
 * @author: zhanglu
 * @create: 2019-10-08 11:14:00
 */
public class ShiroDbRealm extends AuthorizingRealm {

    @Autowired
    private UserAuthService userAuthService;

    /**
     * 身份信息 登录认证
     * @return
     * @throws AuthenticationException
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authcToken) throws AuthenticationException {

        /*
            1、从token 获取 用户的 username
            2、根据username 从数据库获取用户信息
            3、将数据清洗为shirouser的数据结构（用户的基本信息 + 用户的角色）
            4、获取shiro的认证信息
               - 用户密码 + 盐 的 md5 。。。
         */
        UsernamePasswordToken token = (UsernamePasswordToken) authcToken;
        User user = userAuthService.user(token.getUsername());
        ShiroUser shiroUser = userAuthService.shiroUser(user);
        String credentials = user.getPassword();
        String source= user.getSalt();
        ByteSource credentialsSalt = new Md5Hash(source);
        System.out.println(super.getName());
        return new SimpleAuthenticationInfo(shiroUser, credentials, credentialsSalt, super.getName());
    }


    /**
     * 授权信息 权限认证
     * @param principals
     * @return
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        ShiroUser shiroUser = (ShiroUser) principals.getPrimaryPrincipal();
        List<String> roleList = shiroUser.getRoleList();

        Set<String> permissionSet = new HashSet<>();
        Set<String> roleNameSet = new HashSet<>();

        /*
            1、根据每一个角色ID查询对应的菜单url(授权访问路径)，最后组装成集合
            2、根据角色ID，找到该角色对应的角色名称
         */


        for (String roleId : roleList) {
            List<String> permissions = userAuthService.findPermissionsByRoleId(roleId);
            if (permissions != null) {
                for (String permission : permissions) {
                    if (ToolUtil.isNotEmpty(permission)) {
                        permissionSet.add(permission);
                    }
                }
            }
            String roleName = userAuthService.findRoleNameByRoleId(roleId);
            roleNameSet.add(roleName);
        }

        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
        info.addStringPermissions(permissionSet);
        info.addRoles(roleNameSet);
        return info;
    }

    /**
     * 设置认证加密方式
     */
    @Override
    public void setCredentialsMatcher(CredentialsMatcher credentialsMatcher) {
        HashedCredentialsMatcher md5CredentialsMatcher = new HashedCredentialsMatcher();
        md5CredentialsMatcher.setHashAlgorithmName(ShiroKit.hashAlgorithmName);
        md5CredentialsMatcher.setHashIterations(ShiroKit.hashIterations);
        super.setCredentialsMatcher(md5CredentialsMatcher);
    }

}
